package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.tanhua.commons.constants.Constants;
import com.tanhua.dubbo.api.db.MongoQuestionApi;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.DimensionsApi;
import com.tanhua.dubbo.api.mongo.PersonalityApi;
import com.tanhua.dubbo.api.mongo.SoulApi;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.*;
import com.tanhua.model.vo.*;

import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.dubbo.api.mongo.QuestionnaireApi;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;

import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 测灵魂业务层
 *
 * @author youshengfeng
 * @date 2022/2/20 上午 10:51
 */
@Service
@Slf4j
public class TestSoulService {

    @DubboReference
    private QuestionnaireApi questionnaireApi;
    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private PersonalityApi personalityApi;
    @DubboReference
    private DimensionsApi dimensionsApi;
    @DubboReference
    private SoulApi soulApi;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @DubboReference
    private MongoQuestionApi questionApi;

    /**
     * 提交问卷
     *
     * @param answers
     */
    public String handIn(Map<String, List<AnswerVo>> answers) {
        Long userId = UserHolder.getUserId();
        //获得用户性别
        UserInfo userInfo = userInfoApi.findUserInfo(userId);
        String gender = userInfo.getGender();
        List<AnswerVo> answerVoList = answers.get("answers");

        //将试题ID取出，判断出该试题的级别
        AnswerVo answerVo1 = answerVoList.get(0);
        String questionId = answerVo1.getQuestionId();

        Question question = questionApi.findQuestionById(new ObjectId(questionId));
        Integer level = question.getLevel();

        List<ObjectId> objects = answerVoList.stream().map(a -> new ObjectId(a.getOptionId())).collect(Collectors.toList());

        //提交问卷
        String objectId = questionnaireApi.handIn(objects, gender, userId, level);
        //levelKey大key level小key
        String levelKey = Constants.SOUL_TEST_KEY + userId;
        String levelStr = stringRedisTemplate.opsForValue().get(levelKey);
        //为空 级别 查不到就是初级
        if (StringUtils.isEmpty(levelStr)) {
            stringRedisTemplate.opsForValue().set(levelKey, "2");
        } else if ("2".equals(levelStr) && level.equals(2)) {
            //不为空 级别 查到就级别+1
            int integer = Integer.parseInt(levelStr);
            levelStr = String.valueOf(++integer);
            stringRedisTemplate.opsForValue().set(levelKey, levelStr);
        }
        return objectId;
    }

    /**
     * 灵魂测试-查看结果
     *
     * @param reportId
     * @return
     */
    public SoulVo findSoulReport(String reportId) {
        //1.根据报告id查询灵魂(鉴定)表soul
        Soul soul = soulApi.findById(reportId);
        //获取人格类型
        Integer personalityType = soul.getPersonalityType();
        //2.根据人格类型查询灵魂人格表得到Personality对象
        Personality personality = personalityApi.findPersonalityByType(personalityType);
        //3.获取维度id 查询维度表Dimensions
        ObjectId dimensionsId = personality.getDimensionsId();
        Dimensions dimensions = dimensionsApi.findDimensionsById(dimensionsId);

        //4.根据当前用户查询当前用户的详细信息获取性别
        String gender = soul.getGender();
        String newGender = Objects.equals(gender, "man") ? "woman" : "man";

        //5.根据人格类型查询查询灵魂(鉴定)表soul得到用户ids
        List<Soul> soulList = soulApi.findSoulUserIdByType(personalityType, newGender, soul.getLevel());
        List<Long> userIds ;
        if (CollectionUtil.isNotEmpty(soulList)) {
            userIds = CollUtil.getFieldValues(soulList, "userId", Long.class);
        } else {
            userIds = getUserInfo(newGender);
        }
        //6.根据用户ids查询用户详细信息
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(userIds, null);

        //7.构造维度信息list
        List<DimensionsVo> list = new ArrayList<>();
        DimensionsVo dimensionsVo1 = new DimensionsVo("外向", dimensions.getExtroversion());
        DimensionsVo dimensionsVo2 = new DimensionsVo("判断", dimensions.getJudge());
        DimensionsVo dimensionsVo3 = new DimensionsVo("抽象", dimensions.getAbstraction());
        DimensionsVo dimensionsVo4 = new DimensionsVo("理性", dimensions.getReason());
        list.add(dimensionsVo1);
        list.add(dimensionsVo2);
        list.add(dimensionsVo3);
        list.add(dimensionsVo4);

        //8.构造vo返回
        SoulVo soulVo = new SoulVo();
        soulVo.setConclusion(personality.getConclusion());//鉴定结果
        soulVo.setCover(personality.getCover());//鉴定图片
        soulVo.setDimensions(list);//维度

        //用户数据list返回
        List<SimilarYouVo> userInfoVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(userIds)) {
            for (Long userId : userIds) {                  //userid推荐用户的id
                UserInfo userInfo = userInfoMap.get(userId);
                SimilarYouVo userInfoVo = new SimilarYouVo();
                userInfoVo.setAvatar(userInfo.getAvatar());

                userInfoVo.setId(userInfo.getId().intValue());
                userInfoVoList.add(userInfoVo);
            }
            soulVo.setSimilarYou(userInfoVoList);
        } else {
            soulVo.setSimilarYou(null);

        }

        return soulVo;
    }

    /**
     * 获取问卷列表
     */
    public List<QuestionnaireVo> getQuestionnaireIdList() {
        List<QuestionnaireVo> naireVos = new ArrayList<>();
        //1、查询redis查看用户是否做过问卷，如果做过问卷则开放下一级问卷
        String redisKey = Constants.SOUL_TEST_KEY + UserHolder.getUserId();
        //初-1|中-2|高-3
        String level = stringRedisTemplate.opsForValue().get(redisKey);
        Integer levelInt = 1;
        if (!StringUtils.isEmpty(level)) {
            levelInt = Integer.valueOf(level);
        }
        //2、获取各个列表
        List<Option> optionsList = soulApi.getOptionsList();
        List<Question> questionList = soulApi.getQuestionList();
        List<Questionnaire> questionnaireList = soulApi.getQuestionnaireList();
        Map<Integer, ObjectId> resultMap = soulApi.getResultByUserId(UserHolder.getUserId());
        //3、遍历问卷列表，获取Questionnaire对应级别，决定是否开放下一级问卷
        for (Questionnaire questionnaire : questionnaireList) {
            Integer level1 = questionnaire.getLevel();
//            ObjectId objectId = soulApi.getResultByUserId(UserHolder.getUserId(), level1);
            QuestionnaireVo questionnaireVo = new QuestionnaireVo().init(questionnaire, resultMap.get(level1));
            BeanUtils.copyProperties(questionnaire, questionnaireVo);
            if (questionnaire.getLevel() <= levelInt) {
                questionnaireVo.setIsLock(0);
            }
            //获取该questionnaire对应的题目ID(绑定题目与试题),筛选出对应的question
            List<Question> questions = questionnaireVo.getQuestion(questionnaire, questionList);

            List<QuestionVo> list = new ArrayList<>();
            for (Question question : questions) {
                //构建题目表Vo并添加到questionnaireVo中（绑定选项与题目）
                list.add(new QuestionVo().init(question, optionsList));
            }
            questionnaireVo.setQuestions(list);
            naireVos.add(questionnaireVo);
        }

        return naireVos;
    }

    /**
     * 默认相似的人
     *
     * @return
     */
    private List<Long> getUserInfo(String gender) {
        List<Long> list = new ArrayList<>();
        // 随机产生开始的客户id, 从这个客服的id开始，往后取10个
        int startIndex = RandomUtils.nextInt(1, 20);
        List<UserInfo> userInfo = userInfoApi.findOtherSex(gender);
        for (int i = startIndex; i < startIndex + 10; i++) {

            list.add(userInfo.get(i).getId());
        }
        return list;
    }
}






